@file:JvmName("UIContextExtKt")

package com.sea.base.ui

import androidx.annotation.IdRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import com.sea.base.ext.global.allTrue
import com.sea.base.ext.view.requireActivity
import com.sea.base.fragment.FragmentVisibilityChild

inline val IUIContext.currentFragment: Fragment?
    get() {
        currentFragmentManager.fragments.forEach {
            if (it !is com.sea.base.fragment.FragmentVisibilityChild) {
                throw IllegalStateException("该方法只适合继承FragmentVisibilityChild的Fragment")
            }
            if (it.isVisibleParent) {
                return it
            }
        }
        return null
    }

/**
 * @throws IllegalArgumentException 请确保你的Fragment存在，并且是[FragmentVisibilityChild]的子类
 */
@Suppress("NOTHING_TO_INLINE")
inline fun IUIContext.switchFragment(tag: String, @IdRes frameLayoutId: Int = 0): Fragment {
    val fragment = currentFragmentManager.findFragmentByTag(tag)!!
    fragment as com.sea.base.fragment.FragmentVisibilityChild
    switchFragment(fragment, frameLayoutId)
    return fragment
}

/**
 * 切换fragment，如果没有缓存则新建，如果未show则show出来，如果show中则什么都不做
 * 默认使用currentFragment.hasCode 作为tag
 */
@Suppress("NOTHING_TO_INLINE")
inline fun <T> IUIContext.switchFragment(
    newFrag: T,
    @IdRes frameLayoutId: Int = 0,
    tag: String? = null
) where T : Fragment, T : com.sea.base.fragment.FragmentVisibilityChild {
    val safeTag = tag ?: newFrag.hashCode().toString()
    val ft: FragmentTransaction = currentFragmentManager.beginTransaction()
    currentFragment?.let {
        if (it == newFrag) return
        ft.hide(it)
    }
    if (newFrag.isAdded) {
        ft.show(newFrag)
    } else if (frameLayoutId != 0) {
        ft.add(frameLayoutId, newFrag, safeTag)
    }
    ft.commitNow()
}

/**
 * 初始普通权限
 * 注意版本适配，比如：READ_EXTERNAL_STORAGE、通知等
 */
@Suppress("NOTHING_TO_INLINE")
inline fun IUIContext.requestPermission(vararg pNames: String) =
    com.sea.base.permission.PermissionBox(this).setRequestPermission(*pNames)

/**
 * 初始必要权限
 * @param onPermanentlyRejectCallback 当完全拒绝时回调，null表示默认弹窗并引导手动打开[PermissionBox.defaultPermanentlyReject]
 */
@JvmOverloads
@Suppress("NOTHING_TO_INLINE")
inline fun IUIContext.requestMajorPermission(
    vararg pNames: String, noinline onPermanentlyRejectCallback: ((
        permanentlyRejectList: List<com.sea.base.permission.PermissionBean>,
        grantedList: List<com.sea.base.permission.PermissionBean>,
        rejectList: List<com.sea.base.permission.PermissionBean>
    ) -> Unit)? = null
) = com.sea.base.permission.PermissionBox(this).also {
    it.setMajorPermission(*pNames, onPermanentlyRejectCallback = onPermanentlyRejectCallback ?: it.defaultPermanentlyReject())
}

@Suppress("NOTHING_TO_INLINE")
inline fun IUIContext.isGrantedPermission(perName: String) = com.sea.base.permission.PermissionBox.isGranted(requireActivity, perName)


@Suppress("NOTHING_TO_INLINE")
inline fun IUIContext.isAllGrantedPermission(vararg perNames: String) = perNames.allTrue { isGrantedPermission(it) }

